package com.template.utils.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class StringOps extends KeyOps {

    private final ValueOperations<String, Object> stringOperations;

    @Autowired
    public StringOps(RedisTemplate<String, Object> redisTemplate) {
        super(redisTemplate);
        this.stringOperations = redisTemplate.opsForValue();
    }


    /**
     * <h4> String </h4>
     * 普通缓存
     * <li> set _key _value </li>
     * <li> set _key _value xx </li>
     */
    public void set(String key, Object value) {
        stringOperations.set(key, value);
    }

    /**
     * <h4> String </h4>
     * 普通缓存，并设置过期时间
     * <li> set _key _value ex _expire </li>
     */
    public void set(String key, Object value, long expire) {
        setEx(key, expire, value);
    }

    /**
     * <h4> String </h4>
     * 普通缓存，并设置过期时间
     * <li> setex _key _expire _value </li>
     */
    public void setEx(String key, long expire, Object value) {
        stringOperations.set(key, value, expire, TimeUnit.SECONDS);
    }

    /**
     * <h4> String </h4>
     * 普通缓存，若存在则保留旧值
     * <li> setnx  _key _value </li>
     * <li> set  _key _value nx </li>
     */
    public Boolean setNx(String key, Object value) {
        return stringOperations.setIfAbsent(key, value);
    }

    /**
     * <h4> String </h4>
     * 普通缓存，并设置过期时间，若存在则保留旧值
     * <li> set _key _value nx ex _expire </li>
     */
    public Boolean setNx(String key, Object value, long expire) {
        return stringOperations.setIfAbsent(key, value, expire, TimeUnit.SECONDS);
    }

    /**
     * <h4> String </h4>
     * 批量普通缓存
     * <li> set _key1 _value1 _key2 _value2 ... </li>
     */
    public void mSet(Map<String, Object> entry) {
        stringOperations.multiSet(entry);
    }

    /**
     * <h4> String </h4>
     * 批量普通缓存，若存在则保留旧值
     * <li> set _key1 _value1 _key2 _value2 ... </li>
     */
    public Boolean mSetNx(Map<String, Object> entry) {
        return stringOperations.multiSetIfAbsent(entry);
    }

    /**
     * <h4> String </h4>
     * 普通缓存，并返回旧 value
     * <li> set _key _value get </li>
     */
    public Object setAndGet(String key, Object value) {
        return stringOperations.getAndSet(key, value);
    }

    /**
     * <h4> String </h4>
     * 普通缓存，并返回旧 value
     * <li> getset _key _value </li>
     */
    public Object getSet(String key, Object value) {
        return setAndGet(key, value);
    }

    /**
     * <h4> String </h4>
     * 普通缓存获取
     * <li> get _key </li>
     */
    public Object get(String key) {
        return stringOperations.get(key);
    }

    /**
     * <h4> String </h4>
     * 普通缓存截取
     * <li> getrange _key _start _end </li>
     */
    public String getRange(String key, long start, long end) {
        return stringOperations.get(key, start, end);
    }

    /**
     * <h4> String </h4>
     * 覆盖给定 key 所储存的字符串值，覆盖的位置从偏移量 offset 开始。
     * <li> getrange _key _start _end </li>
     *
     * @param offset 覆盖的偏移量
     */
    public void setRange(String key, Object value, long offset) {
        stringOperations.set(key, value, offset);
    }

    /**
     * <h4> String </h4>
     * 普通缓存批量获取
     * <li> mget _key1 _key2 ... </li>
     */
    public List<Object> mGet(String... keys) {
        return mGet(Arrays.asList(keys));
    }

    /**
     * <h4> String </h4>
     * 普通缓存批量获取
     * <li> mget _key1 _key2 ... </li>
     */
    public List<Object> mGet(Collection<String> keys) {
        return stringOperations.multiGet(keys);
    }

    /**
     * <h4> String </h4>
     * 普通缓存获取并删除
     * <li> getdel _key </li>
     */
    public Object getDel(String key) {
        return stringOperations.getAndDelete(key);
    }

    /**
     * <h4> String </h4>
     * 普通缓存获取并取消过期时间
     * <li> getnx _key persist </li>
     */
    public Object getNxAndPersist(String key) {
        return stringOperations.getAndPersist(key);
    }

    /**
     * <h4> String </h4>
     * 普通缓存获取并重新设置过期时间
     * <li> getnx _key ex _expire </li>
     */
    public Object getNxAndExpire(String key, long expire) {
        return stringOperations.getAndExpire(key, expire, TimeUnit.SECONDS);
    }

    /**
     * <h4> String </h4>
     * 普通缓存获取 value 的长度
     * <li> strlen _key </li>
     */
    public Long strlen(String key) {
        return stringOperations.size(key);
    }

    /**
     * <h4> String </h4>
     * 普通缓存拼接，将字符串 value 拼接至末尾
     * <li> append _key _value </li>
     */
    public Integer append(String key, String value) {
        return stringOperations.append(key, value);
    }

    /**
     * <h4> String </h4>
     * 普通缓存 value 自增
     * <li> incr _key </li>
     */
    public Long incr(String key) {
        return stringOperations.increment(key);
    }

    /**
     * <h4> String </h4>
     * 普通缓存增加 value
     * <li> incrby _key _num </li>
     */
    public Long incrBy(String key, long num) {
        return stringOperations.increment(key, num);
    }

    /**
     * <h4> String </h4>
     * 普通缓存增加 value
     * <li> incrbyfloat _key _num </li>
     */
    public Double incrByFloat(String key, double num) {
        return stringOperations.increment(key, num);
    }

    /**
     * <h4> String </h4>
     * 普通缓存 value 自减
     * <li> decr _key </li>
     */
    public Long decr(String key) {
        return stringOperations.decrement(key);
    }

    /**
     * <h4> String </h4>
     * 普通缓存减少 value
     * <li> decrby _key _num </li>
     */
    public Long decrBy(String key, long num) {
        return stringOperations.decrement(key, num);
    }


}
